﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PrVyd.Dialogova_okna;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using PrVyd.Zakladni_tridy;
using System.Xml.Linq;

namespace PrVyd
{

    public partial class mainForm : Form
    {
        private InvoiceManager invcManager = new InvoiceManager();
        private PaymentManager paymentManager = new PaymentManager();

        public mainForm()
        {
            InitializeComponent();

            DatabaseManager.TryCreateDB();
            RefreshInvoices(true);
            RefreshPayments(true);
            RefreshRecordsYears();
            ResetConfig();

        }

        private void RefreshRecordsYears()
        {
            HashSet<string> cbItems = new HashSet<string>();
            foreach (var invc in invcManager.Invoices)
                cbItems.Add(invc.Due.Year.ToString());

            foreach (var payments in paymentManager.Payments)
                cbItems.Add(payments.Date.Year.ToString());

            this.cbTaxYear.Items.Clear();
            foreach (var item in cbItems)
                this.cbTaxYear.Items.Add(item);

            if (this.cbTaxYear.Items.Count > 0)
                this.cbTaxYear.SelectedIndex = 0;

            refreshRecords();

        }

        private void refreshRecords()
        {
            if (this.cbTaxYear.Items.Count == 0 || 
                string.IsNullOrEmpty((this.cbTaxYear.SelectedItem ?? "").ToString()))
            {
                this.dgwRecords.Rows.Clear();
                return;
            }

            int year = int.Parse(this.cbTaxYear.SelectedItem.ToString());

            List<Invoice> invoices = invcManager.Invoices.Where((invc) => invc.Due.Year == year).ToList();
            List<Payment> payments = paymentManager.Payments.Where((payment) => payment.Date.Year == year).ToList();

            this.dgwRecords.Rows.Clear();
            decimal invoiceSum = 0, paymentsSum = 0;
            foreach (var invc in invoices)
            {
                this.dgwRecords.Rows.Add(new Object[] { invc.Due.ToShortDateString(), invc.Number, invc.Customer.Firm, invc.TotalAmount.ToString() + " Kč", "" });
                invoiceSum += invc.TotalAmount;
            }

            foreach (var pay in payments)
            {
                this.dgwRecords.Rows.Add(new Object[] { pay.Date.ToShortDateString(), pay.Number, pay.Description, "", pay.Amount.ToString() + " Kč" });
                paymentsSum += pay.Amount;
            }

            this.lTotalRevenues.Text = "Příjmy celkově: " + invoiceSum + " Kč";
            this.lTotalCosts.Text = "Výdaje celkově: " + paymentsSum + " Kč";
            this.lTaxBase.Text = "Základ daně z příjmu: " + (invoiceSum - paymentsSum) + " Kč";
        }

        private void ResetConfig()
        {
            this.tbBank.Text = ConfigManager.BankCode;
            this.tbBillNumber.Text = ConfigManager.Bill;
            this.tbSupplierCity.Text = ConfigManager.City;
            this.tbDIC.Text = ConfigManager.DIC;
            this.tbICO.Text = ConfigManager.ICO;
            this.tbSupplierName.Text = ConfigManager.Name;
            this.tbSupplierStreet.Text = ConfigManager.Street;
            this.tbSupplierSurname.Text = ConfigManager.Surname;
            this.tbZip.Text = ConfigManager.Zip;
        }

        // add invoice
        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            XmlDocument doc = DatabaseManager.LoadDBXml();
            WFaktura window = new WFaktura(doc);
            if (window.ShowDialog() == DialogResult.OK)
            {
                dgwInvoices.Rows.Add(window.DatagridInfo);
                DatabaseManager.SaveDB(doc);
                RefreshRecordsYears();
            }

        }

        // add payment
        private void addToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            PridejPlatbu dialog = new PridejPlatbu();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                paymentManager.CreatePayment(dialog.DialogPayment);

                this.dgwPayments.Rows.Add(new String[] { dialog.DialogPayment.Number.ToString(), dialog.DialogPayment.Recipient.Firm, dialog.DialogPayment.Amount.ToString() + " Kč", dialog.DialogPayment.Date.ToShortDateString() });
                RefreshRecordsYears();
        
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void RefreshInvoices(bool isInit)
        {
            dgwInvoices.Rows.Clear();
            XDocument doc = DatabaseManager.LoadDBX();
            foreach (Invoice invoice in invcManager.Invoices)
            {
                try
                {
                    dgwInvoices.Rows.Add(invoice.Number, invoice.Customer.Firm,invoice.TotalAmount + " Kč", invoice.Due.ToShortDateString());
                }
                catch (Exception)
                {
                    continue;
                }
            }

            if (!isInit)
                RefreshRecordsYears();
        }

        private void RefreshPayments(bool isInit)
        {
            foreach (var payment in paymentManager.Payments)
                this.dgwPayments.Rows.Add(new object[] { payment.Number, payment.Recipient.Firm, payment.Amount.ToString() + " Kč", payment.Date.ToShortDateString()});

            if (!isInit)
                RefreshRecordsYears();
        }

        private void deleteSelectedToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dgwPayments.SelectedRows)
            {

                String x = row.Cells[0].Value.ToString();
                dgwPayments.Rows.RemoveAt(row.Index);
                paymentManager.DeletePayment(long.Parse(x));
            }
        }

        private void editSelectedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool changed = false;
            foreach (DataGridViewRow row in dgwPayments.SelectedRows)
            {

                String paymentNumber = row.Cells[0].Value.ToString();
                Payment payment = (from z in paymentManager.Payments
                                  where z.Number == Int32.Parse(paymentNumber)
                                  select z).First();

                PridejPlatbu dialogPlatba = new PridejPlatbu();
                dialogPlatba.FillWithPayment(payment);
                if (dialogPlatba.ShowDialog() == DialogResult.OK)
                {
                    paymentManager.UpdatePayment(dialogPlatba.DialogPayment);
                    changed = true;
                }


            }
            if (changed)
            {
                dgwPayments.Rows.Clear();
                RefreshPayments(false);
            }
        }

        private void deleteInvoice_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dgwInvoices.SelectedRows)
            {

                String index = row.Cells[0].Value.ToString();
                dgwInvoices.Rows.RemoveAt(row.Index);
                XDocument doc = DatabaseManager.LoadDBX();
                XElement element = (from z in doc.Descendants("invoice")
                                   where z.Attribute("number").Value.Equals(index)
                                   select z).First();
                element.Remove();
                DatabaseManager.SaveDB(doc);

            }
            RefreshInvoices(false);
        }

        private void editInvoice_Click(object sender, EventArgs e)
        {
            if (dgwInvoices.SelectedRows != null)
            {
                XDocument xDoc = DatabaseManager.LoadDBX();
                foreach (DataGridViewRow row in dgwInvoices.SelectedRows)
                {
                    String invoiceNumber = row.Cells[0].Value.ToString();
                    XElement elem = (from z in xDoc.Descendants("invoice")
                                     where z.Attribute("number").Value.Equals(invoiceNumber)
                                     select z).First();
                    XmlDocument doc = DatabaseManager.LoadDBXml();
                    WFaktura window = new WFaktura(doc);
                    window.FillWithXElement(elem);
                    if (window.ShowDialog() == DialogResult.OK)
                    {
                        XDocument xDocum = XDocument.Parse(doc.OuterXml);
                        (from z in xDocum.Descendants("invoice")
                         where z.Attribute("number").Value.Equals(invoiceNumber.ToString())
                         select z).First().Remove();
                        DatabaseManager.SaveDB(xDocum);
                        RefreshInvoices(false);
                    }
                }
            }
            else
            {
                MessageBox.Show("Nejdříve vyberte fakturu.", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                
            }
        }

        private void cbTaxYear_SelectedIndexChanged(object sender, EventArgs e)
        {
            refreshRecords();
        }

        private void bSaveSettings_Click(object sender, EventArgs e)
        {
            ConfigManager.BankCode = this.tbBank.Text;
            ConfigManager.Bill = this.tbBillNumber.Text;
            ConfigManager.City = this.tbSupplierCity.Text;
            ConfigManager.DIC = this.tbDIC.Text;
            ConfigManager.ICO = this.tbICO.Text;
            ConfigManager.Name = this.tbSupplierName.Text;
            ConfigManager.Street = this.tbSupplierStreet.Text;
            ConfigManager.Surname = this.tbSupplierSurname.Text;
            ConfigManager.Zip = this.tbZip.Text;

        }

        private void bConfigReset_Click(object sender, EventArgs e)
        {
            ResetConfig();
        }


    }
}
